home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / comms / other / slrn / slrn_src / src / misc.c < prev    next >
C/C++ Source or Header  |  1999-05-14  |  39KB  |  1,915 lines

  1. /* -*- mode: C; mode: fold; -*- */
  2. /* Copyright (c) 1998 John E. Davis (davis@space.mit.edu)
  3.  *
  4.  * This file is part of slrn.
  5.  *
  6.  * Slrn is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 2, or (at your option) any
  9.  * later version.
  10.  * 
  11.  * Slrn is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * for more details.
  15.  * 
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with Slrn; see the file COPYING.  If not, write to the Free
  18.  * Software Foundation, 59 Temple Place - Suite 330, 
  19.  * Boston, MA  02111-1307, USA.
  20.  */
  21.  
  22. #include "config.h"
  23. #include "slrnfeat.h"
  24.  
  25. /*{{{ Include Files */
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdarg.h>
  30. #include <signal.h>
  31. #include <ctype.h>
  32. #include <errno.h>
  33. #include <time.h>
  34.  
  35. #ifdef HAVE_STDLIB_H
  36. # include <stdlib.h>
  37. #endif
  38.  
  39. #ifdef HAVE_UNISTD_H
  40. #include <unistd.h>
  41. #endif
  42.  
  43. #if !defined(VMS) && !defined(__WIN32__) && !defined(__NT__)
  44. # define HAS_PASSWORD_CODE    1
  45. # include <pwd.h>
  46. #endif
  47.  
  48. #ifdef VMS
  49. # include "vms.h"
  50. #else
  51. # include <sys/types.h>
  52. # include <sys/stat.h>
  53. #endif
  54.  
  55. #if defined(VMS) && defined(MULTINET)
  56. # include "multinet_root:[multinet.include]netdb.h"
  57. #else
  58. # if defined(__NT__)
  59. #  include <winsock.h>
  60. # else
  61. #  if defined(__WIN32__)
  62. #   define Win32_Winsock
  63. #   include <windows.h>
  64. #  else
  65. #   include <netdb.h>
  66. #   ifndef h_errno
  67. extern int h_errno;
  68. #   endif
  69. #  endif 
  70. # endif 
  71. #endif 
  72.  
  73. #ifdef HAVE_SYS_WAIT_H
  74. # include <sys/wait.h>
  75. #endif
  76.  
  77. #ifdef NeXT
  78. # undef WIFEXITED
  79. # undef WEXITSTATUS
  80. #endif
  81.  
  82. #ifndef WEXITSTATUS
  83. # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
  84. #endif
  85. #ifndef WIFEXITED
  86. # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
  87. #endif
  88.  
  89. #include <slang.h>
  90. #include "jdmacros.h"
  91.  
  92. #include "misc.h"
  93. #include "group.h"
  94. #include "slrn.h"
  95. #include "post.h"
  96. #include "server.h"
  97. #include "util.h"
  98. #include "ttymsg.h"
  99. #include "chmap.h"
  100.  
  101. #if SLRN_HAS_MIME
  102. #include "mime.h"
  103. #endif
  104.  
  105. #ifdef VMS
  106. /* valid filname chars for unix equiv of vms filename */
  107. # define VALID_FILENAME_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_-/"
  108. # include "vms.h"
  109. #endif
  110. /*}}}*/
  111.  
  112. /*{{{ Global Variables */
  113. int Slrn_Full_Screen_Update = 1; 
  114. int Slrn_User_Wants_Confirmation = 1;
  115. int Slrn_Message_Present = 0;
  116. int Slrn_Abort_Unmodified = 0;
  117.  
  118. #ifndef VMS
  119. char *Slrn_SendMail_Command;
  120. #endif
  121.  
  122. char *Slrn_Editor;
  123. char *Slrn_Editor_Post;
  124. char *Slrn_Editor_Score;
  125. char *Slrn_Editor_Mail;
  126.  
  127. Slrn_User_Info_Type Slrn_User_Info;
  128. SLKeyMap_List_Type *Slrn_RLine_Keymap;
  129.  
  130. /*}}}*/
  131. /*{{{ Static Variables */
  132.  
  133. static int Error_Present;
  134. static SLang_RLine_Info_Type *Slrn_Keymap_RLI;
  135. static char *Input_String;
  136. static char *Input_String_Ptr;
  137. static char *Input_Chars_Ptr;
  138. static char *Input_Chars;
  139. static int Beep_Pending;
  140. /*}}}*/
  141.  
  142. static void redraw_message (void);
  143. static void redraw_mini_buffer (void);
  144.  
  145. /*{{{ Screen Update Functions */
  146.  
  147. void slrn_smg_refresh (void)
  148. {
  149.    if (Slrn_TT_Initialized & SLRN_SMG_INIT)
  150.      {
  151.     slrn_push_suspension (0);
  152.     if (Beep_Pending)
  153.       SLtt_beep ();
  154.     Beep_Pending = 0;
  155.     SLsmg_refresh ();
  156.     slrn_pop_suspension ();
  157.      }
  158. }
  159.  
  160.  
  161. void slrn_set_color (int color) /*{{{*/
  162. {
  163.    SLsmg_set_color (color);
  164. }
  165.  
  166. /*}}}*/
  167.  
  168. void slrn_redraw (void) /*{{{*/
  169. {
  170.    if (Slrn_Batch) return;
  171.    
  172.    slrn_push_suspension (0);
  173.    
  174.    SLsmg_cls ();
  175.    Slrn_Full_Screen_Update = 1;
  176.    
  177.    redraw_message ();
  178.    slrn_update_screen ();
  179.    redraw_mini_buffer ();
  180.  
  181.    slrn_smg_refresh ();
  182.    slrn_pop_suspension ();
  183. }
  184.  
  185. /*}}}*/
  186.  
  187. void slrn_print_percent (int row, int col, SLscroll_Window_Type *w) /*{{{*/
  188. {
  189.    int bot_showing;
  190.    unsigned int bot_number;
  191.    
  192.    SLsmg_erase_eol ();
  193.    SLsmg_gotorc (row, col);
  194.    SLsmg_printf ("-- %d/%d", w->line_num, w->num_lines);
  195.  
  196.    bot_number = w->line_num + (w->nrows - w->window_row) - 1;
  197.    
  198.    bot_showing = ((w->bot_window_line == NULL)
  199.           || (w->num_lines == bot_number));
  200.  
  201.    if (w->line_num == w->window_row + 1)
  202.      {
  203.     SLsmg_write_string (bot_showing ? "  (All)" : "  (Top)" );
  204.      }
  205.    else if (bot_showing) SLsmg_write_string("  (Bot)");
  206.    else SLsmg_printf("  (%d%%)", (100 * bot_number) / w->num_lines);
  207.    SLsmg_erase_eol ();
  208. }
  209.  
  210. /*}}}*/
  211.  
  212. void slrn_update_top_status_line (void) /*{{{*/
  213. {
  214.    if (Slrn_Full_Screen_Update == 0) return;
  215.    SLsmg_gotorc (0, 0);
  216.    slrn_set_color (MENU_COLOR);
  217.    SLsmg_printf ("\
  218. slrn %s ** Press '?' for help, 'q' to quit. ** Server: %s",
  219.          Slrn_Version,
  220.          Slrn_Server_Obj->sv_name);
  221.    SLsmg_erase_eol ();
  222.    slrn_set_color (0);
  223. }
  224.  
  225. /*}}}*/
  226.  
  227. /*}}}*/
  228. /*{{{ Message/Error Functions */
  229.  
  230. /* The first character is the color */
  231. static char Message_Buffer[1024];
  232.  
  233. static void redraw_message (void)
  234. {
  235.    int color;
  236.    char *m, *mmax;
  237.  
  238.    if (Slrn_Batch) return;
  239.    
  240.    if (Slrn_Message_Present == 0)
  241.      return;
  242.    
  243.    slrn_push_suspension (0);
  244.  
  245.    SLsmg_gotorc (SLtt_Screen_Rows - 1, 0);
  246.    
  247.    color = Message_Buffer [0];
  248.    m = Message_Buffer + 1;
  249.    
  250.    while (1)
  251.      {
  252.     mmax = slrn_strchr (m, 1);
  253.     if (mmax == NULL)
  254.       mmax = m + strlen(m);
  255.     
  256.     slrn_set_color (color);
  257.     SLsmg_write_nchars (m, (unsigned int) (mmax - m));
  258.     if (*mmax == 0)
  259.       break;
  260.     mmax++;
  261.     if (*mmax == 0)
  262.       break;
  263.     
  264.     slrn_set_color (RESPONSE_CHAR_COLOR);
  265.     SLsmg_write_nchars (mmax, 1);
  266.     m = mmax + 1;
  267.      }
  268.    
  269.    SLsmg_erase_eol ();
  270.    slrn_set_color (0);
  271.    
  272.    slrn_pop_suspension ();
  273. }
  274.  
  275.      
  276. static void vmessage_1 (int color, char *fmt, va_list ap)
  277. {
  278.    vsprintf (Message_Buffer + 1, fmt, ap);
  279.    Message_Buffer[0] = (char) color;
  280.    Slrn_Message_Present = 1;
  281.    redraw_message ();
  282. }
  283.  
  284. static void vmessage (FILE *fp, char *fmt, va_list ap)
  285. {
  286.    if (Slrn_TT_Initialized & SLRN_SMG_INIT)
  287.      vmessage_1 (0, fmt, ap);
  288.    else
  289.      slrn_tty_vmessage (fp, fmt, ap);
  290. }
  291.  
  292. static void verror (char *fmt, va_list ap)
  293. {
  294.    if ((Slrn_TT_Initialized & SLRN_SMG_INIT) == 0)
  295.      {
  296.     slrn_tty_vmessage (stderr, fmt, ap);
  297.      }
  298.    else if (Error_Present == 0)
  299.      {
  300.     slrn_clear_message ();
  301.     Error_Present = 1;
  302.     Beep_Pending = 1;
  303.     vmessage_1 (ERROR_COLOR, fmt, ap);
  304.     SLang_flush_input ();
  305.      }
  306.    
  307.    if (SLang_Error == 0) SLang_Error = INTRINSIC_ERROR;
  308. }
  309.  
  310. /*}}}*/
  311. void slrn_clear_message (void) /*{{{*/
  312. {
  313.    Slrn_Message_Present = Error_Present = 0;
  314.    /* SLang_Error = 0; */
  315.    Beep_Pending = 0;
  316.    SLKeyBoard_Quit = 0;
  317.    
  318.    if ((Slrn_TT_Initialized & SLRN_SMG_INIT) == 0)
  319.      return;
  320.    
  321.    slrn_push_suspension (0);
  322.    SLsmg_gotorc (SLtt_Screen_Rows - 1, 0);
  323.    SLsmg_erase_eol ();
  324.    *Message_Buffer = 0;
  325.    slrn_pop_suspension ();
  326. }
  327.  
  328. /*}}}*/
  329.  
  330. void slrn_va_message (char *fmt, va_list ap)
  331. {
  332.    if (Error_Present == 0)
  333.      vmessage (stderr, fmt, ap);
  334. }
  335.  
  336. int slrn_message (char *fmt, ...) /*{{{*/
  337. {
  338.    va_list ap;
  339.    
  340.    if (Error_Present) return -1;
  341.    va_start(ap, fmt);
  342.    vmessage (stdout, fmt, ap);
  343.    va_end (ap);
  344.    return 0;
  345. }
  346.  
  347. /*}}}*/
  348.  
  349. int slrn_message_now (char *fmt, ...) /*{{{*/
  350. {
  351.    va_list ap;
  352.    
  353.    if (Error_Present) return -1;
  354.    va_start(ap, fmt);
  355.    vmessage (stdout, fmt, ap);
  356.    va_end (ap);
  357.    slrn_smg_refresh ();
  358.    Slrn_Message_Present = 0;
  359.    return 0;
  360. }
  361.  
  362. /*}}}*/
  363.  
  364. void slrn_error (char *fmt, ...) /*{{{*/
  365. {
  366.    va_list ap;
  367.  
  368.    va_start(ap, fmt);
  369.    verror (fmt, ap);
  370.    va_end (ap);
  371. }
  372.  
  373. /*}}}*/
  374.  
  375. void slrn_error_now (unsigned secs, char *fmt, ...) /*{{{*/
  376. {
  377.    va_list ap;
  378.  
  379.    if (fmt != NULL)
  380.      {
  381.     va_start(ap, fmt);
  382.     verror (fmt, ap);
  383.     va_end (ap);
  384.      }
  385.    slrn_smg_refresh ();
  386.    Slrn_Message_Present = 0;
  387.    if (secs) sleep (secs);
  388. }
  389.  
  390. /*}}}*/
  391.  
  392. int slrn_check_batch (void)
  393. {
  394.    if (Slrn_Batch == 0) return 0;
  395.    slrn_error ("This function is not available in batch mode.");
  396.    return -1;
  397. }
  398.  
  399. /*}}}*/
  400.  
  401. /*{{{ File Related Functions */
  402.    
  403.  
  404. #ifdef VMS
  405. /*{{{ VMS Filename fixup functions */
  406.  
  407. static void vms_fix_name(char *name)
  408. {
  409.    int idx, pos;
  410.    
  411.    pos = strspn(name, VALID_FILENAME_CHARS);
  412.    if (pos == strlen(name))
  413.      return;
  414.    for(idx=pos;idx<strlen(name);idx++)
  415.      if (!(isdigit(name[idx]) || isalpha(name[idx]) || (name[idx] == '$') || (name[idx] == '_') || (name[idx] == '-')
  416.        || (name[idx] =